﻿module internal IronLua.Parsing.Cst

open System
open IronLua.Parsing
open IronLua.Runtime

type Expr = 
    | Empty of TokenPosition

    // data
    | Nil of TokenPosition
    | Number of TokenPosition * double
    | String of TokenPosition * string
    | Boolean of TokenPosition * bool
    | ClrObj of TokenPosition * obj
    | Closure of TokenPosition * Guid * (* params *) Expr list * (* body *) Expr list * (* upvaluecount: *) int * (* localcount: *) int * Map<string, Expr>
    | VarArgs of TokenPosition
    | VarArgsExpr of TokenPosition
        
    // metamethods
    | Binary of TokenPosition * string * Expr * Expr
    | Unary of TokenPosition * string * Expr
    | GetIndex of TokenPosition * Expr * Expr
    | SetIndex of TokenPosition * Expr * Expr
    | Call of TokenPosition * Expr * Expr list

    // statements    
    | DefineLocal of TokenPosition * int * int * string * Expr
    | Local of TokenPosition * int * int * string
    | Scope of TokenPosition * Expr list
    | Label of TokenPosition * string
    | Goto of TokenPosition * (* label *) string
    | If of TokenPosition * (* cond *) Expr * (* truepart *) Expr * (* falsepart *) Expr
    | While of TokenPosition * (* cond *) Expr * (* block *) Expr
    | CoalesceResults of TokenPosition * Expr
    | Return of TokenPosition * Expr list
    | Chunk of TokenPosition * Guid * string * Expr list * Expr * int * int

    member this.Position
        with get() = 
            match this with
            | Empty(p)
            | Nil(p)
            | Number(p, _)
            | String(p, _)
            | Boolean(p, _)
            | ClrObj(p, _)
            | Closure(p, _, _, _, _, _, _)
            | VarArgs(p)
            | VarArgsExpr(p)
            | Binary(p, _, _, _)
            | Unary(p, _, _)
            | GetIndex(p, _, _)
            | SetIndex(p, _, _)
            | Call(p, _, _)
            | DefineLocal(p, _, _, _, _)
            | Local(p, _, _, _)
            | Scope(p, _)
            | Label(p, _)
            | Goto (p, _)
            | If(p, _, _, _)
            | While(p, _, _)
            | CoalesceResults(p, _)
            | Return(p, _)                  
            | Chunk (p, _, _, _, _, _, _) -> p

    member this.ConstValue
        with get() =
            match this with
            | Number(_, d) ->   LuaValue.FromDouble(d)
            | String(_, s) ->   LuaValue.FromString(s)
            | Boolean(_, b) ->  LuaValue.FromBool(b)
            | ClrObj(_, o) ->   LuaValue.FromObject(o)
            | _ ->              LuaValue.Nil

